# -*- coding: utf-8 -*-
"""
Module Description: 外显变更方法
Date: 2020/12/23
Author: Peng Ming Yuan
"""
from collections import defaultdict
from copy import deepcopy

from pyshare.const.enums.activity import ActivityType
from pyshare.const.enums.item import ItemType
from pyshare.core.context import temporary_ctx
from pyshare.dal.gameconfig.query import getProfile, getProfileList
from pyshare.dal.repository_impl import CrossShowOwnerRepository, CrossSeasonChooseClothesRepository, \
    CrossSeasonRoleRepository
from pyshare.remote_services.area_services.show_service import AreaShowService
from pyshare.utils.cfg_utils import get_table_by_item_type


class BaseShowManager(object):
    """
    单一外显变更封装
    需要发放的外显道具配置表中必现有GetRank字段
    """

    def __init__(self, item_type, item_id, new_owner_list, source_id):
        self.item_type = item_type
        self.item_id = item_id
        self.old_owner_adt_dict = {t.role_guid: t.server_id for t in
                                   CrossShowOwnerRepository.filter_by_itemtype_itemid_not_sourceid(self.item_type,
                                                                                                   self.item_id,
                                                                                                   source_id)}
        self.new_owner_list = new_owner_list  # [[[rid], server_id]]
        self.source_id = source_id

    def change_show(self):
        """
        批量创建、删除多区服称号
        """
        new_rid_list = []
        server_list = []
        for rid_list, server_id in self.new_owner_list:
            server_list.append(server_id)
            new_rid_list += rid_list  # 当前赛季或活动所有可获得外显玩家
            # 批量创建
            CrossShowOwnerRepository.create_many([{'ItemId': self.item_id, 'RoleGuid': rid,
                                                   'ServerId': server_id, 'ItemType': self.item_type,
                                                   'SourceId': self.source_id}
                                                  for rid in rid_list])

        # 对比生成需要删除的rid
        need_del_dict = defaultdict(list)
        for rid, server_id in self.old_owner_adt_dict.iteritems():
            need_del_dict[server_id].append(rid)
            server_list.append(server_id)

        # 删除外显拥有者记录
        CrossShowOwnerRepository.delete_by_itemtype_itemid_not_sourceid(self.item_type, self.item_id,
                                                                        self.source_id)

        # 随机挑选一个区服调用创建和删除所有区服称号
        if server_list:
            server_list = list(set(server_list))
            server_id = server_list[0]
            AreaShowService.change_many_server_cross_show(self.item_type, self.item_id, self.new_owner_list,
                                                          server_list, server_id, need_del_dict)


class BaseMultipleShowManager(object):
    """
    同一排名可选外显变更封装
    支持多人多外显
    需要发放的外显道具配置表中必须有GetRank字段
    """

    def __init__(self, item_type, item_id, new_owner_list, source_id):
        self.item_type = item_type
        self.item_id = item_id
        self.source_id = source_id
        self.old_owner_dict = self.get_old_owner_dict()
        self.new_owner_list = new_owner_list  # [[[rid], server_id]]

    def get_old_owner_dict(self):
        # 读取同活动同排名的其他外显
        tc_table_name, key_name = get_table_by_item_type(self.item_type)
        item_cfg = getProfile(tc_table_name, **{key_name: self.item_id})
        item_cfg_list = getProfileList(tc_table_name, GetRank=item_cfg.GetRank)
        old_owner_dict = dict()
        for item_cfg in item_cfg_list:
            old_owner_adt_dict = {t.role_guid: t.server_id for t in
                                  CrossShowOwnerRepository.filter_by_itemtype_itemid_not_sourceid(self.item_type,
                                                                                                  item_cfg.ItemId,
                                                                                                  str(self.source_id))}
            old_owner_dict[str(item_cfg.ItemId)] = old_owner_adt_dict
        return old_owner_dict

    def change_show(self):
        """
        批量创建、删除多区服外显
        """
        new_rid_list = []
        server_list = []
        for rid_list, server_id in self.new_owner_list:
            server_list.append(server_id)
            new_rid_list += rid_list  # 所有可获得外显玩家
            owner_list = deepcopy(rid_list)
            # 读取道具是否可以永久解锁
            tc_table_name, key_name = get_table_by_item_type(self.item_type)
            item_cfg = getProfile(tc_table_name, **{key_name: self.item_id})

            # 解锁次数大于永久解锁次数的玩家不记录在跨服外显拥有者记录表
            if item_cfg.ForeverUnlockTimes:
                if item_cfg.ActivityType == ActivityType.CrossSeason:
                    with temporary_ctx(server_id=server_id):
                        # 读取时装选择次数
                        choose_data_list = CrossSeasonChooseClothesRepository.filter_by_clothes_id(rid_list,
                                                                                                   self.item_id)
                        for choose_data in choose_data_list:
                            add_times = 1
                            # 读取多增加次数
                            role_data = CrossSeasonRoleRepository.get_by_seasonid_srvid_rid(int(self.source_id),
                                                                                            choose_data.role_guid,
                                                                                            server_id)
                            dan_cfg = getProfile("TcCrossSeasonDan", DanId=role_data.dan)
                            add_times += dan_cfg.AddChooseTimes
                            if choose_data.choose_times+add_times >= item_cfg.ForeverUnlockTimes:
                                owner_list.remove(choose_data.role_guid)

            # 批量创建
            CrossShowOwnerRepository.create_many([{'ItemId': self.item_id, 'RoleGuid': rid,
                                                   'ServerId': server_id, 'ItemType': self.item_type,
                                                   'SourceId': self.source_id}
                                                  for rid in owner_list])

        # 对比生成需要删除的rid
        need_del_item_dict = dict()
        for show_id, old_owner_adt_dict in self.old_owner_dict.iteritems():
            need_del_dict = defaultdict(list)
            for rid, server_id in old_owner_adt_dict.iteritems():
                if show_id == self.item_id and (rid in new_rid_list):
                    continue
                need_del_dict[server_id].append(rid)
                server_list.append(server_id)
            need_del_item_dict[str(show_id)] = need_del_dict

        # 随机挑选一个区服调用创建和删除所有区服外显
        if server_list:
            server_list = list(set(server_list))
            server_id = server_list[0]
            AreaShowService.change_many_server_cross_multiple_show(self.item_type, self.item_id, self.new_owner_list,
                                                                   server_list, server_id, need_del_item_dict,
                                                                   self.source_id)

        for del_item_id, old_owner_adt_dict in self.old_owner_dict.iteritems():
            # 删除外显拥有者记录
            CrossShowOwnerRepository.delete_by_itemtype_itemid_not_sourceid(self.item_type, int(del_item_id),
                                                                            self.source_id)


class CrossSeasonBubbleManager(BaseShowManager):
    """
    九州之巅气泡框变更
    """
    def __init__(self, item_id, new_owner_list, source_id):
        """
        :param item_id: 道具id
        :param new_owner_list:  [[[rid], server_id]]
        :param source_id:  来源id
        """
        self.item_type = ItemType.Bubble
        super(CrossSeasonBubbleManager, self).__init__(self.item_type, item_id, new_owner_list, source_id)


class CrossSeasonClothesManager(BaseShowManager):
    """
    九州之巅普通时装变更
    """
    def __init__(self, item_id, new_owner_list, source_id):
        """
        :param item_id: 道具id
        :param new_owner_list:  [[[rid], server_id]]
        :param source_id:  来源id
        """
        self.item_type = ItemType.Clothes
        super(CrossSeasonClothesManager, self).__init__(self.item_type, item_id, new_owner_list, source_id)


class CrossSeasonMultipleClothesManager(BaseMultipleShowManager):
    """
    九州之巅普通时装变更
    """
    def __init__(self, item_id, new_owner_list, source_id):
        """
        :param item_id: 道具id
        :param new_owner_list:  [[[rid], server_id]]
        :param source_id:  来源id
        """
        self.item_type = ItemType.Clothes
        super(CrossSeasonMultipleClothesManager, self).__init__(self.item_type, item_id, new_owner_list, source_id)
        self.old_owner_adt_dict = {t.role_guid: t.server_id for t in
                                   CrossShowOwnerRepository.filter_by_itemtype_itemid_not_sourceid(self.item_type,
                                                                                                   self.item_id,
                                                                                                   source_id)}


class ActivityShowManager(object):
    """
    活动外显变更管理 (多活动筛选server_list)
    """
    def __init__(self, item_type, item_id, new_owner_list, source_id, server_list):
        """
        :param item_id: 道具id
        :param new_owner_list:  [[[rid], server_id]]
        :param source_id:  来源id
        :param server_list: 参与区服
        """
        self.item_type = item_type
        self.item_id = item_id
        self.server_list = server_list
        self.old_owner_adt_dict = {t.role_guid: t.server_id for t in
                                   CrossShowOwnerRepository.filter_by_itemtype_itemid_server_list(self.item_type,
                                                                                                  self.item_id,
                                                                                                  self.server_list)}
        self.new_owner_list = new_owner_list  # [[[rid], server_id]]
        self.source_id = source_id

    def change_show(self):
        """
        批量创建、删除多区服外显
        """
        new_rid_list = []
        for rid_list, server_id in self.new_owner_list:
            new_rid_list += rid_list
            new_list = [rid for rid in rid_list if rid not in self.old_owner_adt_dict]  # 可获得外显但目前未拥有
            # 批量创建
            CrossShowOwnerRepository.create_many([{'ItemType': self.item_type,
                                                   'RoleGuid': rid,
                                                   'ServerId': server_id,
                                                   'ItemId': self.item_id,
                                                   'SourceId': self.source_id} for rid in new_list])
        # 对比生成需要删除的rid
        need_del_dict = defaultdict(list)
        for rid, server_id in self.old_owner_adt_dict.iteritems():
            if rid in new_rid_list:
                continue
            need_del_dict[server_id].append(rid)

        # 根据区服批量删除外显
        for server_id, rid_list in need_del_dict.iteritems():
            CrossShowOwnerRepository.delete_by_itemtype_itemid_ridlist_serverid(item_type=self.item_type,
                                                                                item_id=self.item_id,
                                                                                rid_list=rid_list,
                                                                                server_id=server_id)
        # 随机挑选一个区服调用创建和删除所有区服外显
        if self.server_list:
            server_list = list(set(self.server_list))
            server_id = server_list[0]
            AreaShowService.change_many_server_show(self.item_type, self.item_id, server_id, self.new_owner_list, server_list)

